use consistent unit suffixes. (#1353)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Sat, 19 Oct 2024 19:55:51 +0000 (13:55 -0600)
committerGitHub <noreply@github.com>
Sat, 19 Oct 2024 19:55:51 +0000 (13:55 -0600)
* use consistent unit suffixes.

This is a user visible change. The suffixes for the distance
option of the arcdist, interpolate, radius and position filters
and the add option of the height filter are different.

* drop unused includes

* whitespace

* terminate fatal messages.

* change simplify to process distances in meters.

This simplifies option value parsing.
There is no user visible difference.

* define MYNAME in cc not h.

19 files changed:
arcdist.cc
gui/filterdata.cc
height.cc
height.h
interpolate.cc
interpolate.h
position.cc
radius.cc
reference/filter1.txt
reference/help.txt
smplrout.cc
testo.d/interpolate.test
testo.d/position.test
xmldoc/filters/options/arc-distance.xml
xmldoc/filters/options/height-add.xml
xmldoc/filters/options/interpolate-distance.xml
xmldoc/filters/options/interpolate-time.xml
xmldoc/filters/options/position-distance.xml
xmldoc/filters/options/radius-distance.xml

index 96760db9a3b676e3d8377942c6a3938248cd87b8..c72ee1a8975a89d2130f746074635836f44c8d2a 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <cmath>                  // for round
 #include <cstdio>                 // for printf, sscanf
-#include <cstdlib>                // for strtod
 #include <tuple>                  // for tie, tuple
 
 #include <QByteArray>             // for QByteArray
@@ -78,8 +77,8 @@ void ArcDistanceFilter::arcdist_arc_disp_wpt_cb(const Waypoint* arcpt2)
                                                      waypointp->position());
         }
 
-        /* convert radians to float point statute miles */
-        dist = radtomiles(dist);
+        /* convert radians to meters */
+        dist = radtometers(dist);
 
         if (ed->distance > dist) {
           ed->distance = dist;
@@ -206,22 +205,17 @@ void ArcDistanceFilter::process()
 
 void ArcDistanceFilter::init()
 {
-  char* fm;
-
   if ((!arcfileopt && !rteopt && !trkopt) ||
       (arcfileopt && (rteopt || trkopt)) ||
       (rteopt && trkopt)) {
     fatal(MYNAME ": Incompatible or incomplete option values!\n");
   }
 
-  pos_dist = 0;
+  pos_dist = 0.0;
 
   if (distopt) {
-    pos_dist = strtod(distopt, &fm);
-
-    if ((*fm == 'k') || (*fm == 'K')) {
-      /* distance is kilometers, convert to mile */
-      pos_dist *= kMilesPerKilometer;
+    if (parse_distance(distopt, &pos_dist, kMetersPerMile, MYNAME) == 0) {
+      fatal(MYNAME ": No distance specified with distance option.\n");
     }
   }
 }
index 0003c83ce9039f08b5b0b04a289fbc6ecee99421..3c77d3a4ad07abb7be52be66904eaf69cc0468ad 100644 (file)
@@ -30,10 +30,11 @@ QStringList WayPtsFilterData::makeOptionString()
     return args;
   }
 
+  static const QVector<QString> radius_units = {"mi", "km"};
   if (radius) {
     args << QString("-x");
     args << QString("radius,distance=%1%2,lat=%3,lon=%4")
-         .arg(radiusVal).arg("MK"[radiusUnit]).arg(latVal, 0, 'f', 8).arg(longVal, 0, 'f', 8);
+         .arg(radiusVal).arg(radius_units.at(radiusUnit)).arg(latVal, 0, 'f', 8).arg(longVal, 0, 'f', 8);
   }
   if (duplicates && (shortNames || locations)) {
     args << QString("-x");
@@ -47,9 +48,10 @@ QStringList WayPtsFilterData::makeOptionString()
     args << s;
   }
 
+  static const QVector<QString> position_units = {"ft", "m"};
   if (position) {
     args << QString("-x");
-    args << QString("position,distance=%1%2").arg(positionVal).arg("FM"[positionUnit]);
+    args << QString("position,distance=%1%2").arg(positionVal).arg(position_units.at(positionUnit));
   }
   return args;
 }
index c2694c85dc25fd44ca130891ee0198d39432b997..c7d56414ef1f377dc51018e3b565962deba3445f 100644 (file)
--- a/height.cc
+++ b/height.cc
@@ -26,7 +26,6 @@
 #include "height.h"
 #include <cmath>    // for floor
 #include <cstdint>  // for int8_t
-#include <cstdlib>  // for strtod
 
 #define MYNAME "height"
 
@@ -96,18 +95,11 @@ void HeightFilter::correct_height(const Waypoint* wpt)
 
 void HeightFilter::init()
 {
-  char* unit;
-
+  addf = 0.0;
   if (addopt != nullptr) {
-    addf = strtod(addopt, &unit);
-
-    if (*unit == 'f' || *unit== 'F') {
-      addf = FEET_TO_METERS(addf);
-    } else if ((*unit != 'm') && (*unit != 'M') && (*unit != '\0'))  {
-      fatal(MYNAME ": Invalid unit (\"%c\")! Please use \"m\" for meter or \"f\" for feet.\n", *unit);
+    if (parse_distance(addopt, &addf, 1.0, MYNAME) == 0) {
+      fatal(MYNAME ": No height specified with add option.");
     }
-  } else {
-    addf = 0.0;
   }
 }
 
index e39044fad94f7bbb24494e56841be79df05cc1d2..8b3333076faf3603248a47f976599838abf1ff7f 100644 (file)
--- a/height.h
+++ b/height.h
@@ -55,7 +55,7 @@ private:
 
   QVector<arglist_t> args = {
     {
-      "add", &addopt, "Adds a constant value to every altitude (meter, append \"f\" (x.xxf) for feet)",
+      "add", &addopt, "Adds a constant value to every altitude",
       nullptr, ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX, nullptr
     },
     {
index 6de250a8e049ca23ae779ee9fd3c57f9cc5d8a47..577e80ff3b0edbc124d0baaa6640526d933931d0 100644 (file)
@@ -91,7 +91,7 @@ void InterpolateFilter::process_rte(route_head* rte)
         // interpolate even if time is running backwards.
         npts = std::abs(*timespan) / max_time_step;
       } else if (opt_dist != nullptr) {
-        double distspan = radtomiles(gcdist(pos1, wpt->position()));
+        double distspan = radtometers(gcdist(pos1, wpt->position()));
         npts = distspan / max_dist_step;
       }
       if (!std::isfinite(npts) || (npts >= INT_MAX)) {
@@ -142,7 +142,6 @@ void InterpolateFilter::process_rte(route_head* rte)
 
 void InterpolateFilter::init()
 {
-  char* fm;
   if ((opt_time != nullptr) && (opt_dist != nullptr)) {
     fatal(FatalMsg() << MYNAME ": Can't interpolate on both time and distance.");
   } else if ((opt_time != nullptr) && opt_route) {
@@ -153,10 +152,8 @@ void InterpolateFilter::init()
       fatal(FatalMsg() << MYNAME ": interpolation time should be positive!");
     }
   } else if (opt_dist != nullptr) {
-    max_dist_step = strtod(opt_dist, &fm);
-    if ((*fm == 'k') || (*fm == 'K')) {
-      /* distance is kilometers, convert to miles */
-      max_dist_step *= kMilesPerKilometer;
+    if (parse_distance(opt_dist, &max_dist_step, kMetersPerMile, MYNAME) == 0) {
+      fatal(FatalMsg() << MYNAME ": no distance specified with distance option!");
     }
     if (max_dist_step <= 0) {
       fatal(FatalMsg() << MYNAME ": interpolation distance should be positive!");
index 79a8d7a187dfb53d90b12066be7b68017aaed742..269a5d23ed98f4b8ebb4e756b38abfaf44b60368 100644 (file)
@@ -62,7 +62,7 @@ private:
       "0", nullptr, nullptr
     },
     {
-      "distance", &opt_dist, "Distance interval in miles or kilometers",
+      "distance", &opt_dist, "Distance interval",
       nullptr, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING,
       ARG_NOMINMAX, nullptr
     },
index 3b4fb07a7bbdc31af56abd0069f397d9b431cd58..c334315aae1ec42bea65de7b65a93ad9499c5606 100644 (file)
@@ -32,6 +32,7 @@
 #include "src/core/datetime.h"  // for DateTime
 
 #if FILTERS_ENABLED
+#define MYNAME "Position filter"
 
 /* tear through a waypoint queue, processing points by distance */
 void PositionFilter::position_runqueue(const WaypointList& waypt_list, int qtype)
@@ -112,12 +113,8 @@ void PositionFilter::init()
   check_time = false;
 
   if (distopt != nullptr) {
-    char* fm;
-    pos_dist = strtod(distopt, &fm);
-
-    if (!((*fm == 'm') || (*fm == 'M'))) {
-      /* distance is feet */
-      pos_dist = FEET_TO_METERS(pos_dist);
+    if (parse_distance(distopt, &pos_dist, kMetersPerFoot, MYNAME) == 0) {
+      fatal(MYNAME ": No distance specified with distance option.\n");
     }
   }
 
index d261d94a48bda61cd3e3ecbc1c81d4d4e35b14fa..3e11c2fdeff536c26467ef82b810dd5a604cd172 100644 (file)
--- a/radius.cc
+++ b/radius.cc
 
 
 #if FILTERS_ENABLED
+#define MYNAME "Radius filter"
 
 void RadiusFilter::process()
 {
   foreach (Waypoint* waypointp, *global_waypoint_list) {
-    double dist = radtomiles(gcdist(waypointp->position(),
+    double dist = radtometers(gcdist(waypointp->position(),
                                     home_pos->position()));
 
     if ((dist >= pos_dist) == !exclopt) {
@@ -97,12 +98,8 @@ void RadiusFilter::init()
   pos_dist = 0;
 
   if (distopt != nullptr) {
-    char* fm;
-    pos_dist = strtod(distopt, &fm);
-
-    if ((*fm == 'k') || (*fm == 'K')) {
-      /* distance is kilometers, convert to miles */
-      pos_dist *= kMilesPerKilometer;
+    if (parse_distance(distopt, &pos_dist, kMetersPerMile, MYNAME) == 0) {
+      fatal(MYNAME ": No distance specified with distance option.\n");
     }
   }
 
index 8241c29ba2865478a5becc14d48ca4679d2a622d..6cb9768fd203c2c4719c938075d65ed4b1ed098e 100644 (file)
@@ -22,10 +22,10 @@ option      radius  maxcount        Output no more than this number of points       integer         1               htt
 option radius  asroute Put resulting waypoints in route of this name   string                          https://www.gpsbabel.org/WEB_DOC_DIR/filter_radius.html#fmt_radius_o_asroute
 interpolate    Interpolate between trackpoints https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html
 option interpolate     time    Time interval in seconds        float           0               https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_time
-option interpolate     distance        Distance interval in miles or kilometers        string                          https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_distance
+option interpolate     distance        Distance interval       string                          https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_distance
 option interpolate     route   Interpolate routes instead      boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/filter_interpolate.html#fmt_interpolate_o_route
 height Manipulate altitudes    https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html
-option height  add     Adds a constant value to every altitude (meter, append "f" (x.xxf) for feet)    float                           https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html#fmt_height_o_add
+option height  add     Adds a constant value to every altitude float                           https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html#fmt_height_o_add
 option height  wgs84tomsl      Converts WGS84 ellipsoidal height to orthometric height (MSL)   boolean                         https://www.gpsbabel.org/WEB_DOC_DIR/filter_height.html#fmt_height_o_wgs84tomsl
 track  Manipulate track lists  https://www.gpsbabel.org/WEB_DOC_DIR/filter_track.html
 option track   move    Correct trackpoint timestamps by a delta        string                          https://www.gpsbabel.org/WEB_DOC_DIR/filter_track.html#fmt_track_o_move
index 99a933530b5066a94848cc72c3c7153dad724f21..4919782464c8df91629ab8955c3feb740b759b4c 100644 (file)
@@ -414,7 +414,7 @@ Supported data filters:
          correct               Use coords from duplicate points 
        interpolate           Interpolate between trackpoints                   
          time                  Time interval in seconds 
-         distance              Distance interval in miles or kilometers 
+         distance              Distance interval 
          route                 Interpolate routes instead 
        nuketypes             Remove all waypoints, tracks, or routes           
          waypoints             Remove all waypoints from data stream 
@@ -494,7 +494,7 @@ Supported data filters:
          del                   Delete source data after transformation 
          timeless              Create transformed points without times 
        height                Manipulate altitudes                              
-         add                   Adds a constant value to every altitude (meter, ap 
+         add                   Adds a constant value to every altitude 
          wgs84tomsl            Converts WGS84 ellipsoidal height to orthometric h 
        swap                  Swap latitude and longitude of all loaded points  
        validate              Validate internal data structures                 
index eb53881268901499148ac0f4956d94efabf17784..18522b90c4fe6ebafdb6f739cc1878ae9153ad4b 100644 (file)
@@ -66,7 +66,7 @@
 
 #include "defs.h"
 #include "smplrout.h"
-#include "grtcirc.h"            // for gcdist, linedist, radtometers, radtomiles, linepart
+#include "grtcirc.h"            // for gcdist, linedist, radtometers, linepart
 #include "src/core/datetime.h"  // for DateTime
 
 
@@ -96,13 +96,13 @@ double SimplifyRouteFilter::compute_track_error(const neighborhood& nb) const
   double track_error;
   switch (metric) {
   case metric_t::crosstrack:
-    track_error = radtomiles(linedist(
+    track_error = radtometers(linedist(
                                wpt1->position(),
                                wpt2->position(),
                                wpt3->position()));
     break;
   case metric_t::length:
-    track_error = radtomiles(
+    track_error = radtometers(
                     gcdist(wpt1->position(), wpt3->position()) +
                     gcdist(wpt3->position(), wpt2->position()) -
                     gcdist(wpt1->position(), wpt2->position()));
@@ -293,11 +293,8 @@ void SimplifyRouteFilter::init()
     if (metric == metric_t::relative) {
       error = strtod(erroropt, nullptr);
     } else {
-      int res = parse_distance(erroropt, &error, 1.0, MYNAME);
-      if (res == 0) {
-        error = 0;
-      } else if (res == 2) { /* parameter with unit */
-        error = METERS_TO_MILES(error);
+      if (parse_distance(erroropt, &error, kMetersPerMile, MYNAME) == 0) {
+        fatal(MYNAME ": No value specified with error option.\n");
       }
     }
   }
index c061573162e12d1350f9778725b70c64bb8daa7d..c313edf1c72a86b56208605110c2d66723b491dc 100644 (file)
@@ -13,10 +13,13 @@ echo 'IFIELD LON_DECIMAL, "", "%.6f"' >> ${TMPDIR}/interp.style
 echo 'IFIELD PATH_DISTANCE_METERS, "", "%.0f"' >> ${TMPDIR}/interp.style
 echo 'IFIELD ALT_METERS, "", "%.3f"' >> ${TMPDIR}/interp.style
 echo 'IFIELD TIMET_TIME_MS, "", "%lld"' >> ${TMPDIR}/interp.style
-gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50m -o gpx -F ${TMPDIR}/interp.gpx -o xcsv,style=${TMPDIR}/interp.style -F ${TMPDIR}/interp.csv
+gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50mi -o gpx -F ${TMPDIR}/interp.gpx -o xcsv,style=${TMPDIR}/interp.style -F ${TMPDIR}/interp.csv
 compare ${REFERENCE}/track/interptrack.gpx ${TMPDIR}/interp.gpx 
 compare ${REFERENCE}/track/interptrack.csv ${TMPDIR}/interp.csv
 
+gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,distance=50 -o gpx -F ${TMPDIR}/interp2.gpx
+compare ${REFERENCE}/track/interptrack.gpx ${TMPDIR}/interp2.gpx 
+
 gpsbabel -t -i gpx -f ${REFERENCE}/track/simpletrack.gpx -x interpolate,time=1 -o gpx -F ${TMPDIR}/tinterp.gpx -o xcsv,style=${TMPDIR}/interp.style -F ${TMPDIR}/tinterp.csv
 compare ${REFERENCE}/track/tinterptrack.gpx ${TMPDIR}/tinterp.gpx 
 compare ${REFERENCE}/track/tinterptrack.csv ${TMPDIR}/tinterp.csv
index 90e66e44ee1786684eb535134952d387c9a6548f..32d2899b8dc0f32f539cf6e6ad013c7ced6307fa 100644 (file)
@@ -5,7 +5,7 @@
 #
 rm -f ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2
 gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -o csv -F ${TMPDIR}/filterpos.csv1
-gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -f ${REFERENCE}/geocaching.loc -x position,distance=5f \
+gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -f ${REFERENCE}/geocaching.loc -x position,distance=5ft \
                -o csv -F ${TMPDIR}/filterpos.csv2
 sort_and_compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2
 
index b2ce7b246b5a72c8709f08e3e66c0c006679c4fa..a27db8c279dea80e4c227ad3f5d84309722794fa 100644 (file)
@@ -8,6 +8,16 @@ without being discarded.  Points that are closer to the arc are kept, while
 points that are further away are discarded.
 </para>
 <para>
-Distances may be specified in miles (3M) or kilometers (5K).  If no units
-are specified, the distance is assumed to be in miles.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be miles.
 </para>
index 60f44f0dd7f184b375cb62263504bfe09a595b40..5a1f9eac65f7e53e0eeb3ecf9df069ba44f8a828 100644 (file)
@@ -2,5 +2,16 @@
 Adds a constant value to every altitude. You can specify negative numbers to subtract the value.
 </para>
 <para>
-If no unit is specified, (m)eters are assumed. You can override this by attaching a "f" for feet to the number.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3.5m</member>
+<member>'ft' or 'feet' for feet, e.g. 11.483ft</member>
+<member>'k' or 'km' for kilometers, e.g 0.0035km</member>
+<member>'nm' for nautical miles, e.g. 0.0018898nm</member>
+<member>'mi' for miles, e.g. 0.0021748mi</member>
+<member>'fa' for fathoms, e.g. 1.9138fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be meters.
 </para>
index 6275e555a16452c913c2ee26caacf830fdfbb702..c986d00354350fb729ae3162eb13126423aa3ba5 100644 (file)
@@ -1,11 +1,21 @@
 <para>
-This option specifies the maximum allowable distance between points in the
+This option specifies the maximum allowable distance between adjacent points in the
 track.  If two points in the track are further apart than this value, new
 points will be inserted between them.
 </para>
 <para>
-This value may be specified in units of miles (3M, 3.5M) or kilometers (5K, 5.7K).  If
-no units are specified, the units are assumed to be miles.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be miles.
 </para>
 <para>
 Either this option or the <option>time</option> must be specified.
index 2f2202853fca3b2bcb38313063a7d13a1f81873a..88325a30cc70959ca4f83d7d35a59b59b78b9535 100644 (file)
@@ -1,5 +1,5 @@
 <para>
-This option specifies the maximum allowable time interval between points in the
+This option specifies the maximum allowable time interval between adjacent points in the
 track.  If two points in the track are further apart than this value, new
 points will be inserted between them.
 </para>
index 03bc9be0eae46524492e7f2ae5569f2daff53734..0dcef61712fadd569d17a0843b70463ddbe351c2 100644 (file)
@@ -3,6 +3,16 @@ This option specifies the minimum allowable distance between two points.  If
 two points are closer than this distance, only one of them is kept.
 </para>
 <para>
-Distances may be expressed in feet (30f) or meters (10m).  If no unit is
-specified, the distance is assumed to be in feet.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be feet.
 </para>
index 3b4d950c520001aee4e5495a1de5a9f200e5da84..3e0092aaa318613b3961495f26be1138125103e1 100644 (file)
@@ -8,6 +8,16 @@ will be kept and points further away will be removed (unless the
 <option>exclude</option> option is specified.)
 </para>
 <para>
-Distances may be expressed in miles (3M) or kilometers (4K).  If no units
-are provided, the distance is assumed to be in miles.
+The units may be specified by appending a suffix to the supplied number:
+</para>
+<simplelist type="vert">
+<member>'m' for meters, e.g. 3500.0m</member>
+<member>'ft' or 'feet' for feet, e.g. 11483ft</member>
+<member>'k' or 'km' for kilometers, e.g 3.5000km</member>
+<member>'nm' for nautical miles, e.g. 1.8898nm</member>
+<member>'mi' for miles, e.g. 2.1748mi</member>
+<member>'fa' for fathoms, e.g. 1913.82fa</member>
+</simplelist>
+<para>
+If no units are specified, the units are assumed to be miles.
 </para>